package frontend.user.product.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import backend.attribute.manager.AttributeManager;
import backend.attribute.manager.AttributeSetManager;
import backend.category.manager.CategoryManager;
import backend.product.manager.ProductAttributeSetManager;
import backend.product.manager.ProductManager;
import backend.product.manager.ProductTypeManager;
import backend.product.manager.UserManager;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

import core.attribute.model.Attribute;
import core.attribute.model.AttributeSet;
import core.attribute.model.AttributeValue;
import core.category.model.Category;
import core.category.model.CategoryType;
import core.product.model.Product;
import core.product.model.ProductAddress;
import core.product.model.ProductAv;
import core.product.model.ProductOwner;
import core.product.model.ProductType;
import core.profile.model.BasicProfile;
import frontend.user.product.manager.UserProductManager;

public class UserProductController extends ActionSupport  
{
	private static final long serialVersionUID = -4008768088656606508L;
	private UserProductManager upm ;
	private UserManager um ;
	private ProductManager pm ;
	private CategoryManager cm ;
	private AttributeManager am ;
	private AttributeSetManager asm ;
	private ProductTypeManager ptm ;
	private ProductAttributeSetManager pasm ;
	private List<Product> userProducts ;
	private Long userId ;
	private List<CategoryType> categoryTypes;
	private List<Category> continents ;
	private List<Category> countries ;
	private List<Category> states ;
	private List<Category> regions ;
	private List<Category> cities ;
	// product Data
	private String name ;
	private Long uuid ;
	private String sku ;
	private boolean enabled ;
	private Long continentId ;
	private Long countryId ;
	private String stateId ;
	private String regionId  ;
	private String cityId ;
	private Product product ;
	private String errorMsg ;
	private boolean isproduct ;
	private Map<String,String> categoryMap ;
	private ProductAddress productAddress ;
	private Long prodOwnerId ;
	private Long productId ;
	
	public UserProductController()
	{
		upm = new UserProductManager();
		um = new UserManager();
		cm = new CategoryManager();
		pm = new ProductManager();
		am = new AttributeManager();
		asm = new AttributeSetManager();
		pasm = new ProductAttributeSetManager();
		ptm = new ProductTypeManager();
	}
	public String execute() throws Exception
	{	
		// userType PropertyManager =2, Owner=3
		List<Product> p = new ArrayList<Product>();
		BasicProfile bp = um.getUserByUuid(this.getUserId());
		Iterator<ProductOwner> poItr = new ArrayList<ProductOwner>().iterator() ;
		if(bp.getUsertype()==3)
		{
			//poItr = upm.getUserProducts(bp).iterator();
		}
		else if(bp.getUsertype()==2)
		{
			//poItr = upm.getManagerProducts(bp).iterator();
		}
		while(poItr.hasNext())
		{
			//p.add(poItr.next().getProduct());
		}
		this.setUserProducts(p);
		return SUCCESS;
	}
	public Long checkUserLogin()
	{
		Long uuid = null;
		Map<String, Object> session = ActionContext.getContext().getSession();
		uuid = (Long) session.get("uuid");
		
		return uuid ;
	}
	public String amenitiesInfo()
	{
		Long userId = this.checkUserLogin() ;
		if(userId == null)
		{
			return ERROR ;
		}
		Long prodId = this.getProductId();
		if(prodId!=null)
		{
			Product p = pm.getProductByUuid(prodId); 
			BasicProfile owner = um.getUserByUuid(userId);
			ProductOwner productOwner = pm.getProductOwnerByProductAndOwner(p, owner);
			if(productOwner !=  null)
			{
				this.setProduct(p);
				this.setIsproduct(true);
			}
		}
		return SUCCESS ;
	}
	public String descriptionInfo()
	{
		Long userId = this.checkUserLogin() ;
		if(userId == null)
		{
			return ERROR ;
		}
		Long prodId = this.getProductId();
		if(prodId!=null)
		{
			Product p = pm.getProductByUuid(prodId); 
			BasicProfile owner = um.getUserByUuid(userId);
			ProductOwner productOwner = pm.getProductOwnerByProductAndOwner(p, owner);
			if(productOwner !=  null)
			{
				this.setProduct(p);
				this.setIsproduct(true);
			}
		}
		return SUCCESS ;
	}
	public String newProduct()
	{ 
		Long userId = this.checkUserLogin() ;
		if(userId == null)
		{
			return ERROR ;
		}
		Long prodId = this.getProductId();
		if(prodId!=null)
		{
			Product p = pm.getProductByUuid(prodId); 
			BasicProfile owner = um.getUserByUuid(userId);
			ProductOwner productOwner = pm.getProductOwnerByProductAndOwner(p, owner);
			if(productOwner !=  null)
			{
				this.setProduct(p);
				this.setIsproduct(true);
				this.setCategoryMap(pm.getProductCategoryMap(p.getUuid()));
				ProductAddress pa = pm.getProductAddress(p);
				if(pa == null)
				{
					pa = new ProductAddress();
					pa.setProduct(p);
					pm.saveProductAddress(pa);
				}
				this.setProductAddress(pa);
			}
	
			return SUCCESS;
		}
		this.setContinents(cm.getCategoryByType(cm.getCategoryTypeByName("continent")));
		this.setIsproduct(false);
		return SUCCESS;
	}
	public String saveProduct()
	{
		// Check for error Validation
		int newFlag = 0 ;
		Product p = pm.getProductBySku(this.getSku());
		this.setContinents(cm.getCategoryByType(cm.getCategoryTypeByName("continent")));
		if(p != null)
		{
			this.setErrorMsg("Product with SKU " + sku + " allready exists.");
			BasicProfile owner = um.getUserByUuid(this.getProdOwnerId());
			ProductOwner productOwner = pm.getProductOwnerByProductAndOwner(p, owner);
			if(productOwner !=  null)
			{
				this.setProduct(p);
				this.setIsproduct(true);
				this.setCategoryMap(pm.getProductCategoryMap(p.getUuid()));
				ProductAddress pa = pm.getProductAddress(p);
				if(pa == null)
				{
					pa = new ProductAddress();
					pa.setProduct(p);
					pm.saveProductAddress(pa);
				}
				this.setProductAddress(pa);
			}
	
			return SUCCESS;
		}	
		if(p == null)
		{
			p = new Product();
			newFlag = 1 ;
			p.setSku(this.getSku());
		}
		// code for create Category Path...
		p.setEnabled(this.isEnabled());
		p.setName(this.getName());
		pm.saveProduct(p);
		CategoryType ctContinent = cm.getCategoryTypeByName("continent");
		CategoryType ctCountry = cm.getCategoryTypeByName("country");
		Category continent = cm.getCategoryByUuid(this.getContinentId());
		Category country = cm.getCategoryByUuid(this.getCountryId());
		CategoryType ctState = cm.getCategoryTypeByName("state");
		Category state = getOrCreateCategory(this.getStateId(),country,ctState);
		CategoryType ctRegion = cm.getCategoryTypeByName("region");
		Category region = getOrCreateCategory(this.getRegionId(),state,ctRegion);
		CategoryType ctCity = cm.getCategoryTypeByName("city");
		Category city = getOrCreateCategory(this.getCityId(),region,ctCity);
		if(newFlag == 1)
		{
			// set product to category world....
			Category world = cm.getCategoryByName("world");
			cm.addProduct(world, p);
			// add product to category continent
			cm.addProduct(continent, p);
			//add product to category country
			cm.addProduct(country, p);
			// create category state if not exists
			cm.addProduct(state, p);
			// create category region if not exists
			cm.addProduct(region, p);
			// create category city if not exists
			cm.addProduct(city, p);
			//put value in ProductOwner.java
			ProductOwner po = new ProductOwner();
			po.setProduct(p);
			BasicProfile user = um.getUserByUuid(userId);
			//propManager = 2, owner = 3
			po.setOwner(user);	
			upm.save(po);
		}
		
	
		return SUCCESS;
	}
	public Category getOrCreateCategory(String value,Category parent,CategoryType ct)
	{
		Category c = null ;
		boolean isString = false ;
		try
		{
			uuid = Long.parseLong(value);
			c=cm.getCategoryByUuid(uuid);
		}
		catch(NumberFormatException nfe)
		{
			isString = true ;
		}
		if(isString)
		{
			//System.out.println("Number is a String  " + num);
			c=new Category();
			c.setName(value);
			c.setCategoryType(ct);
			c.setParent(parent);
			c.setDepth(parent.getDepth()+1);
			cm.save(c);
			c.setPath(parent.getPath()+"/"+c.getUuid());
			cm.save(c);
		}
		return c;
	}
	public Map<String,String> getAttributeValue(String attributeSet ,Product p)
	{
		Map<String,String> value = new HashMap<String,String>() ;
		AttributeSet as = asm.getAttributeSetByName(attributeSet);
		Iterator<ProductAv> pavs = pasm.getProductAvByAttributeSetAndProduct(p, as).iterator();
		while(pavs.hasNext())
		{
			ProductAv pav = pavs.next();
			value.put(pav.getAttribute().getName() , pav.getValue());
		}
		return value;
	}
	public Map<ProductType,Boolean> getProductType(Product p)
	{
		 Map<ProductType,Boolean> ptmap = new HashMap<ProductType, Boolean>();
		 Iterator<ProductType> ptItr = p.getProductType().iterator();
		 
		 while(ptItr.hasNext())
		 {
			 ProductType pt = ptItr.next();
			 ptmap.put(pt,true);
		 }
		 ptItr = pm.getgetAllProductType().iterator();
		 while(ptItr.hasNext())
		 {
			 ProductType pt = ptItr.next();
			 if(ptmap.get(pt) == null)
			 {
				 ptmap.put(pt,false);
			 }
			 
		 }
		 return ptmap ;
	}
	public List<ProductAv> getProductAvByAttributeSet(String attributeSet,Product p)
	{
		List<ProductAv> productAv = new ArrayList<ProductAv>();
		AttributeSet as = asm.getAttributeSetByName("Attractions");
		productAv=pasm.getProductAvByAttributeSetAndProduct(p, as);
		return productAv ;
	}
	public boolean ifChecked(Set<AttributeValue> avs,AttributeValue av)
	{
		Iterator<AttributeValue> avItr = avs.iterator();
		while(avItr.hasNext())
		{
			AttributeValue localAv = avItr.next();
			if(localAv.getUuid().equals(av.getUuid()))
			{
				return true ;
			}
		}
		return false ;
	}
	
	public List<Product> getUserProducts() 
	{
		return userProducts;
	}
	public void setUserProducts(List<Product> userProducts) 
	{
		this.userProducts = userProducts;
	}
	public void setUserId(Long userId) 
	{
		this.userId = userId;
	}
	public Long getUserId() 
	{
		return userId;
	}
	public List<Category> getContinents() {
		return continents;
	}
	public void setContinents(List<Category> continents) {
		this.continents = continents;
	}
	public List<Category> getCountries() {
		return countries;
	}
	public void setCountries(List<Category> countries) {
		this.countries = countries;
	}
	public List<Category> getStates() {
		return states;
	}
	public void setStates(List<Category> states) {
		this.states = states;
	}
	public List<Category> getRegions() {
		return regions;
	}
	public void setRegions(List<Category> regions) {
		this.regions = regions;
	}
	public List<Category> getCities() {
		return cities;
	}
	public void setCities(List<Category> cities) {
		this.cities = cities;
	}
	public List<CategoryType> getCategoryTypes() {
		return categoryTypes;
	}
	public void setCategoryTypes(List<CategoryType> categoryTypes) {
		this.categoryTypes = categoryTypes;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getSku() {
		return sku;
	}
	public void setSku(String sku) {
		this.sku = sku;
	}
	public boolean isEnabled() {
		return enabled;
	}
	public void setEnabled(boolean enabled) {
		this.enabled = enabled;
	}
	public Long getContinentId() {
		return continentId;
	}
	public void setContinentId(Long continentId) {
		this.continentId = continentId;
	}
	public Long getCountryId() {
		return countryId;
	}
	public void setCountryId(Long countryId) {
		this.countryId = countryId;
	}
	public String getStateId() {
		return stateId;
	}
	public void setStateId(String stateId) {
		this.stateId = stateId;
	}
	public String getRegionId() {
		return regionId;
	}
	public void setRegionId(String regionId) {
		this.regionId = regionId;
	}
	public String getCityId() {
		return cityId;
	}
	public void setCityId(String cityId) {
		this.cityId = cityId;
	}
	public Product getProduct() {
		return product;
	}
	public void setProduct(Product product) {
		this.product = product;
	}
	public Long getUuid() {
		return uuid;
	}
	public void setUuid(Long uuid) {
		this.uuid = uuid;
	}
	/**
	 * @return the errorMsg
	 */
	public String getErrorMsg() {
		return errorMsg;
	}
	/**
	 * @param errorMsg the errorMsg to set
	 */
	public void setErrorMsg(String errorMsg) {
		this.errorMsg = errorMsg;
	}
	/**
	 * @return the isproduct
	 */
	public boolean isIsproduct() {
		return isproduct;
	}
	/**
	 * @param isproduct the isproduct to set
	 */
	public void setIsproduct(boolean isproduct) {
		this.isproduct = isproduct;
	}
	/**
	 * @return the categoryMap
	 */
	public Map<String, String> getCategoryMap() {
		return categoryMap;
	}
	/**
	 * @param categoryMap the categoryMap to set
	 */
	public void setCategoryMap(Map<String, String> categoryMap) {
		this.categoryMap = categoryMap;
	}
	/**
	 * @return the productAddress
	 */
	public ProductAddress getProductAddress() {
		return productAddress;
	}
	/**
	 * @param productAddress the productAddress to set
	 */
	public void setProductAddress(ProductAddress productAddress) {
		this.productAddress = productAddress;
	}
	/**
	 * @return the prodOwnerId
	 */
	public Long getProdOwnerId() {
		return prodOwnerId;
	}
	/**
	 * @param prodOwnerId the prodOwnerId to set
	 */
	public void setProdOwnerId(Long prodOwnerId) {
		this.prodOwnerId = prodOwnerId;
	}
	/**
	 * @return the productId
	 */
	public Long getProductId() {
		return productId;
	}
	/**
	 * @param productId the productId to set
	 */
	public void setProductId(Long productId) {
		this.productId = productId;
	}
	
}
